/**
 * Copyright (c) 2018-2023, NXOS Development Team
 * SPDX-License-Identifier: Apache-2.0
 * 
 * Contains: atomic for riscv64
 * 
 * Change Logs:
 * Date           Author            Notes
 * 2023-08-24     JasonHu           Init
 */

#include <nxos/atomic.h>

void NX_AtomicSet(NX_Atomic *atomic, NX_AtomicValue value)
{
    atomic->value = value;
}

NX_AtomicValue NX_AtomicGet(NX_Atomic *atomic)
{
    return atomic->value;
}

void NX_AtomicAdd(NX_Atomic *atomic, NX_AtomicValue value)
{
    /* gcc build-in functions */
    __sync_fetch_and_add(&atomic->value, value);
}

void NX_AtomicSub(NX_Atomic *atomic, NX_AtomicValue value)
{
    __sync_fetch_and_sub(&atomic->value, value);
}

void NX_AtomicInc(NX_Atomic *atomic)
{
    __sync_fetch_and_add(&atomic->value, 1);
}

void NX_AtomicDec(NX_Atomic *atomic)
{
    __sync_fetch_and_sub(&atomic->value, 1);
}

void NX_AtomicSetMask(NX_Atomic *atomic, NX_AtomicValue mask)
{
    __sync_fetch_and_or(&atomic->value, mask);
}

void NX_AtomicClearMask(NX_Atomic *atomic, NX_AtomicValue mask)
{    
    __sync_fetch_and_and(&atomic->value, ~mask);
}

NX_AtomicValue NX_AtomicSwap(NX_Atomic *atomic, NX_AtomicValue newValue)
{
    return __sync_lock_test_and_set(&((atomic)->value), newValue);
}

NX_AtomicValue NX_AtomicCAS(NX_Atomic *atomic, NX_AtomicValue old, NX_AtomicValue newValue)
{
    return __sync_val_compare_and_swap(&atomic->value, old, newValue);
}
